{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "9a5a9a74-4519-40ca-8d5a-7fd3a6d5b6b9",
   "metadata": {},
   "source": [
    "# Introduction To Function Calling!\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "341ccbdf-42cc-4e51-a343-385ecf994077",
   "metadata": {},
   "source": [
    "### Writing A Local Python Tool"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "06e3e128-ed92-4555-8bd2-ed1b3e15dcea",
   "metadata": {
    "height": 149
   },
   "outputs": [],
   "source": [
    "from matplotlib import pyplot as plt\n",
    "\n",
    "def plot_some_points(x : list, y : list):\n",
    "  \"\"\"\n",
    "  Plots some points!\n",
    "  \"\"\"\n",
    "  plt.plot(x, y)\n",
    "  plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9c52c5b4-ab33-44d5-8c30-3c5c9e04848c",
   "metadata": {
    "height": 30
   },
   "outputs": [],
   "source": [
    "USER_QUERY = \"Hey can you plot y=10x where x=1, 2, 3 for me?\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3599b238-a6f0-4911-aed8-5d20f3098ee5",
   "metadata": {
    "height": 30
   },
   "outputs": [],
   "source": [
    "plot_some_points(x=[1, 2, 3], y=[10, 20, 30])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "29eb62ec-fac5-46fb-82b2-8d4b5b330d48",
   "metadata": {
    "height": 217
   },
   "outputs": [],
   "source": [
    "prompt = \\\n",
    "f'''\n",
    "Function:\n",
    "def plot_some_points(x : list, y : list):\n",
    "  \"\"\"\n",
    "  Plots some points!\n",
    "  \"\"\"\n",
    "  plt.plot(x, y)\n",
    "  plt.show()\n",
    "\n",
    "User Query: {USER_QUERY}<human_end>\n",
    "'''"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e3dd9ba2-e674-4dc1-b483-3907720a7642",
   "metadata": {
    "height": 47
   },
   "outputs": [],
   "source": [
    "from utils import query_raven\n",
    "function_call = query_raven(prompt)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "71709bdf-a1d8-446f-b215-8cb6bb71a28a",
   "metadata": {
    "height": 30
   },
   "outputs": [],
   "source": [
    "print (function_call)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "65e8b372-78d7-43d3-9772-3c83d80db8f2",
   "metadata": {
    "height": 30
   },
   "outputs": [],
   "source": [
    "exec(function_call)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b5fc3460-8266-47c1-9dc5-7721ab962816",
   "metadata": {},
   "source": [
    "#### Try Your Own!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b7e188d2-6d9a-43b5-b16e-ee48e88301e4",
   "metadata": {
    "height": 30
   },
   "outputs": [],
   "source": [
    "USER_QUERY = \"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6dfa73d3-445e-4153-90d1-7cbca1daf91e",
   "metadata": {
    "height": 251
   },
   "outputs": [],
   "source": [
    "prompt = \\\n",
    "f'''\n",
    "Function:\n",
    "def plot_some_points(x : list, y : list):\n",
    "  \"\"\"\n",
    "  Plots some points!\n",
    "  \"\"\"\n",
    "  plt.plot(x, y)\n",
    "  plt.show()\n",
    "\n",
    "User Query: {USER_QUERY}<human_end>\n",
    "'''\n",
    "from utils import query_raven\n",
    "function_call = query_raven(prompt)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f4e43ecd-83c7-43ab-9aef-a50cd84def7e",
   "metadata": {
    "height": 30
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "bf31b770-0d54-43b1-a7c3-61099c9a4036",
   "metadata": {},
   "source": [
    "### Let's Try Another Example!"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ff8d2609-71c0-4164-abf3-b74e8e1f2df5",
   "metadata": {},
   "source": [
    "#### Let's define a function"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "83f7086e-eccb-46c7-a35b-716757a0bb47",
   "metadata": {
    "height": 812
   },
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import matplotlib.patches as patches\n",
    "\n",
    "def draw_clown_face(face_color='yellow', eye_color='black', \n",
    "                    nose_color='red'):\n",
    "    \"\"\"\n",
    "    Draws a customizable, simplified clown face using matplotlib.\n",
    "\n",
    "    Parameters:\n",
    "    - face_color (str): Color of the clown's face. Default is 'yellow'.\n",
    "    - eye_color (str): Color of the clown's eyes. Default is 'black'.\n",
    "    - nose_color (str): Color of the clown's nose. Default is 'red'.\n",
    "\n",
    "    This function creates a plot displaying a simplified clown face, where essential facial features' size, position, and color can be customized. \n",
    "    \"\"\"\n",
    "    # Constants\n",
    "    face_radius = 0.4\n",
    "    nose_radius = 0.1\n",
    "    nose_x, nose_y = 0.5, 0.5\n",
    "    mouth_x, mouth_y = 0.5, 0.3\n",
    "    mouth_color = 'black'\n",
    "    eye_size = 0.05\n",
    "    mouth_size = (0.3, 0.1)\n",
    "    eye_offset=(0.15, 0.15)\n",
    "    mouth_theta = (200, 340)\n",
    "\n",
    "    fig, ax = plt.subplots()\n",
    "    # Face\n",
    "    face = patches.Circle((0.5, 0.5), face_radius, color=face_color, fill=True)\n",
    "    ax.add_patch(face)\n",
    "    # Eyes\n",
    "    eye_left = patches.Circle((0.5-eye_offset[0], 0.5+eye_offset[1]), eye_size, color=eye_color, fill=True)\n",
    "    eye_right = patches.Circle((0.5+eye_offset[0], 0.5+eye_offset[1]), eye_size, color=eye_color, fill=True)\n",
    "    ax.add_patch(eye_left)\n",
    "    ax.add_patch(eye_right)\n",
    "    # Nose\n",
    "    nose = patches.Circle((nose_x, nose_y), nose_radius, color=nose_color, fill=True)\n",
    "    ax.add_patch(nose)\n",
    "    # Mouth\n",
    "    mouth = patches.Arc((mouth_x, mouth_y), mouth_size[0], mouth_size[1], angle=0, \n",
    "                        theta1=mouth_theta[0], theta2=mouth_theta[1], color=mouth_color, linewidth=2)\n",
    "    ax.add_patch(mouth)\n",
    "    # Setting aspect ratio to 'equal' to ensure the face is circular\n",
    "    ax.set_aspect('equal')\n",
    "    # Remove axes\n",
    "    ax.axis('off')\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d32b55ca-60f5-4646-a184-fd3d20b4f431",
   "metadata": {},
   "source": [
    "#### Let's Define A Prompt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d9ea3eb0-baef-4cde-868f-2cb1f62e1f2e",
   "metadata": {
    "height": 387
   },
   "outputs": [],
   "source": [
    "USER_QUERY = \\\n",
    "\"Hey can you draw a pink clown face with a red nose\" \n",
    "\n",
    "raven_prompt = \\\n",
    "'''\n",
    "Function:\n",
    "def draw_clown_face(face_color='yellow', \n",
    "                    eye_color='black',\n",
    "                    nose_color='red'):\n",
    "    \"\"\"\n",
    "    Draws a customizable, simplified clown face using matplotlib.\n",
    "\n",
    "    Parameters:\n",
    "    - face_color (str): Color of the clown's face.\n",
    "    - eye_color (str): Color of the clown's eyes.\n",
    "    - nose_color (str): Color of the clown's nose.\n",
    "    \"\"\"\n",
    "\n",
    "User Query: {query}<human_end>\n",
    "'''\n",
    "raven_prompt_with_query = raven_prompt.format(query=USER_QUERY)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d1ccdb8f-776e-4f2f-9894-2cdac7c988f6",
   "metadata": {
    "height": 30
   },
   "outputs": [],
   "source": [
    "print (raven_prompt_with_query)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d647732a-f5d3-449d-b3e4-6bf3ac4e0173",
   "metadata": {
    "height": 64
   },
   "outputs": [],
   "source": [
    "from utils import query_raven\n",
    "raven_call = query_raven(raven_prompt_with_query)\n",
    "print (raven_call)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6600282e-adc3-451b-86fd-abffc99c9a8c",
   "metadata": {},
   "source": [
    "#### Let's Run The Call"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "889012ee-61fd-424f-99a0-323d80488403",
   "metadata": {
    "height": 30
   },
   "outputs": [],
   "source": [
    "exec(raven_call)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7dd944b7-dc29-4d39-a933-8a6884b29459",
   "metadata": {},
   "source": [
    "#### Make Your Own Clown!\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "70575e53-b6bb-43d5-8124-fe5548342746",
   "metadata": {
    "height": 132
   },
   "outputs": [],
   "source": [
    "USER_QUERY = \"\"\n",
    "raven_prompt_with_query = raven_prompt.format(query=USER_QUERY)\n",
    "\n",
    "from utils import query_raven\n",
    "raven_call = query_raven(raven_prompt_with_query)\n",
    "print (raven_call)\n",
    "exec(raven_call)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a924a827-3315-4520-8371-d5a1afd525b6",
   "metadata": {},
   "source": [
    "#### Using OpenAI FC"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "752c6644-9086-465b-9493-62f1d8971774",
   "metadata": {
    "height": 302
   },
   "outputs": [],
   "source": [
    "import json\n",
    "from openai import OpenAI\n",
    "from dotenv import load_dotenv\n",
    "import os\n",
    "\n",
    "_ = load_dotenv()\n",
    "\n",
    "def query_openai(msg, functions=None):\n",
    "  load_dotenv()\n",
    "  GPT_MODEL = \"gpt-3.5-turbo\"\n",
    "\n",
    "  openai_client = OpenAI(api_key=os.environ[\"OPENAI_API_KEY\"])\n",
    "  openai_response = openai_client.chat.completions.create(\n",
    "    model = GPT_MODEL,\n",
    "    messages = [{'role': 'user', 'content': msg}],\n",
    "    tools = functions)\n",
    "  return openai_response"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "779c7540-7426-4199-8a34-6fe8f18aa08e",
   "metadata": {
    "height": 472
   },
   "outputs": [],
   "source": [
    "openai_function = {\n",
    "  \"type\": \"function\",\n",
    "  \"function\": {\n",
    "    \"name\": \"draw_clown_face\",\n",
    "    \"description\": \"Draws a customizable, simplified clown face using matplotlib.\",\n",
    "    \"parameters\": {\n",
    "      \"type\": \"object\",\n",
    "      \"properties\": {\n",
    "        \"face_color\": {\n",
    "          \"type\": \"string\",\n",
    "          \"description\": \"Color of the clown's face.\"\n",
    "        },\n",
    "        \"eye_color\": {\n",
    "          \"type\": \"string\",\n",
    "          \"description\": \"Color of the clown's eyes.\"\n",
    "        },\n",
    "        \"nose_color\": {\n",
    "          \"type\": \"string\",\n",
    "          \"description\": \"Color of the clown's nose.\"\n",
    "        }\n",
    "        }\n",
    "      }\n",
    "    }\n",
    "  }\n",
    "\n",
    "openai_msg = \\\n",
    "\"Hey can you draw a pink clown face with a red nose\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "487db628-adbb-499c-bfe5-29219a41dc82",
   "metadata": {
    "height": 47
   },
   "outputs": [],
   "source": [
    "result = query_openai(openai_msg, functions=[openai_function])\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5c23bdc0-16eb-46bb-885f-cf8a4d214201",
   "metadata": {
    "height": 30
   },
   "outputs": [],
   "source": [
    "print (result.choices[0].message.tool_calls[0].function)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "854b0bc1-7762-49ff-af44-80a064f87a8d",
   "metadata": {
    "height": 64
   },
   "outputs": [],
   "source": [
    "tool_name = result.choices[0].message.tool_calls[0].function.name\n",
    "tool_args = result.choices[0].message.tool_calls[0].function.arguments\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "78458b2b-6dc8-420c-b78d-c88d4efecd0f",
   "metadata": {
    "height": 47
   },
   "outputs": [],
   "source": [
    "function_call = f\"{tool_name}(**{tool_args})\"\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8f09c84e-4a10-41bc-8d7f-238eed1ecb4a",
   "metadata": {
    "height": 30
   },
   "outputs": [],
   "source": [
    "print (function_call)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "347a4c0b-1831-483c-8221-3112a29a4433",
   "metadata": {
    "height": 30
   },
   "outputs": [],
   "source": [
    "exec(function_call)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "587204e4-ce73-4eae-855e-ef0d06654670",
   "metadata": {
    "height": 30
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
